package com.erastep.util;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.earstep.connectionpool.ConnectionPoolFactory;
import com.erastep.pojo.DataColumn;
import com.erastep.pojo.Message;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

/**
 * @category 通讯端点
 * @author DXB
 * 
 */
public class Endpoint {
	public String run(String req) {
		GsonBuilder builder = new GsonBuilder();
		Gson gson = builder.create();
		Type type = new TypeToken<Message>() {
		}.getType();
		Message message = gson.fromJson(req, type);
		DataColumn[] cols = message.getDatas();
		return exec(cols);
	}

	/**
	 * @category 根据json 执行具体内容
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private String exec(DataColumn[] cols) {
		// 返回客户端的数据
		Message message = new Message();
		// 标识执行失败
		message.setCode(0);
		ConnectionPoolFactory factory = ConnectionPoolFactory.getInstance();
		Connection conn = null;
		try {
			conn = factory.getConnection("core");
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		try {
			for (int i = 0; i < cols.length; i++) {
				DataColumn column = cols[i];
				String resfield = column.getResult();
				String pojo = column.getPojo();
				Properties ps = PropertyUtil.loadProperties("pojo.properties");
				String clzss = ps.getProperty(pojo);
				Class c = Class.forName(clzss);
				Object obj = c.newInstance();
				Map<String, String> map = column.getProperties();
				switch (column.getStatus()) {
				// 查询指令
				case 1: {
					if (cols.length > i + 1) {
						if (cols[i + 1].getStatus() == 8) {
							// 修改指令
							break;
						}
					}
					Field tableNameField = c.getField("tableName");
					tableNameField.setAccessible(true);
					String tableName = tableNameField.get(obj).toString();
					String sql = "select " + resfield + " from " + tableName
							+ " where 1=1 ";
					Set keySet = map.entrySet();
					Iterator iterator = keySet.iterator();
					while (iterator.hasNext()) {
						String key = iterator.next().toString();
						map.get(key);
						sql += "and " + key + "=?";
					}
					PreparedStatement statement = conn.prepareStatement(sql);
					iterator = keySet.iterator();
					int index = 0;
					while (iterator.hasNext()) {
						i++;
						String key = iterator.next().toString();
						if (String.class == c.getField(key).getType()) {
							statement.setString(index, map.get(key));
						} else if (int.class == c.getField(key).getType()) {
							statement.setInt(index,
									Integer.parseInt(map.get(key)));
						}
					}
					ResultSet res = statement.executeQuery();
					column.setDatas(perfect(res));
					break;
				}
					// 增加指令
				case 2: {

					break;
				}
					// 删除指令
				case 4: {

					break;
				}
				}
			}
			conn.commit();
			// 标识执行成功
			message.setCode(1);
		} catch (Exception ex) {
			ex.printStackTrace();
			try {
				conn.rollback();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return "";
	}

	private List<Map<String, Object>> perfect(ResultSet rs) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			ResultSetMetaData metaData = rs.getMetaData();
			while (rs.next()) {
				Map<String, Object> map = new HashMap<String, Object>();
				for (int i = 0; i < metaData.getColumnCount(); i++) {
					int type = metaData.getColumnType(i + 1);
					switch (type) {
					case -7: {// bit
						map.put(metaData.getColumnLabel(i + 1),
								rs.getBoolean(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 5: {// smallint
						map.put(metaData.getColumnLabel(i + 1),
								rs.getInt(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 4: {// integer
						map.put(metaData.getColumnLabel(i + 1),
								rs.getInt(metaData.getColumnLabel(i + 1)));
						break;
					}
					case -5: {// bigint
						map.put(metaData.getColumnLabel(i + 1),
								rs.getInt(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 6: {// float
						map.put(metaData.getColumnLabel(i + 1),
								rs.getFloat(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 7: {// real
						map.put(metaData.getColumnLabel(i + 1),
								rs.getString(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 8: {// double
						map.put(metaData.getColumnLabel(i + 1),
								rs.getDouble(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 1: {// char
						map.put(metaData.getColumnLabel(i + 1),
								rs.getString(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 12: {// varchar
						map.put(metaData.getColumnLabel(i + 1),
								rs.getString(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 91: {// date
						map.put(metaData.getColumnLabel(i + 1),
								rs.getDate(metaData.getColumnLabel(i + 1)));
						break;
					}
					case 92: {// time
						map.put(metaData.getColumnLabel(i + 1),
								rs.getTime(metaData.getColumnLabel(i + 1)));
						break;
					}
					case -15: {// nchar
						map.put(metaData.getColumnLabel(i + 1),
								rs.getString(metaData.getColumnLabel(i + 1)));
						break;
					}
					case -9: {// nvarchar
						map.put(metaData.getColumnLabel(i + 1),
								rs.getString(metaData.getColumnLabel(i + 1)));
						break;
					}
					}
				}
			}
		} catch (Exception e) {

		}
		return list;
	}
}
